package Tudy

import (
	"fmt"
	"sort"
)

//NFA确定化过程，首先你要先找到入口节点，然后根据入口节点和它的空闭包到达的点给放入起始节点中
//然后根据起始节点集合通过a这条路径去寻找它所到达的集合，然后存起来，再深入寻找空引用到达的点继续找
//首先先构造图，a路径，b路径
//直接用map集合里面再套一个map集合map[byte]map[byte]byte/第byte的元素通过byte到达的点
//ans集合怎么构造呢，map[[10]byte]map[byte][10  ]byte
//[10]byte{}代表空集合

type GraphStruct struct {
	GraphStructByA [10]byte
	GraphStructByB [10]byte
}

func Tmain()  {

	//NullSum:=[10]byte{} //代表空集合
	GraPh:=make(map[byte]map[byte][]byte)  //NFA图
	//手动初始化NFA图
	for i:='0';i<='9';i++{
		GraPh[byte(i)]=make(map[byte][]byte)
	}
	for i:='0';i<='9';i++{
		GraPh[byte(i)]['e']=make([]byte,0)
	}
	for i:='0';i<='9';i++{
		GraPh[byte(i)]['a']=make([]byte,0)
	}
	for i:='0';i<='9';i++{
		GraPh[byte(i)]['b']=make([]byte,0)
	}
	//手动输入边,e代表伊普西隆弧
	GraPh['0']['e']=append(GraPh['0']['e'],'1','7')
	GraPh['1']['e']=append(GraPh['1']['e'],'2','4')
	GraPh['2']['a']=append(GraPh['2']['a'],'3')
	GraPh['3']['e']=append(GraPh['3']['e'],'6')
	GraPh['4']['b']=append(GraPh['4']['b'],'5')
	GraPh['5']['e']=append(GraPh['5']['e'],'6')
	GraPh['6']['e']=append(GraPh['6']['e'],'1','7')
	GraPh['7']['a']=append(GraPh['7']['a'],'8')
	GraPh['8']['b']=append(GraPh['8']['b'],'9')

	Res:=make(map[[10]byte]GraphStruct)//确定后的结果集
	visit:=make(map[[10]byte]bool)//判断该集合是不是检查过
	StructQueue:=make([][10]byte,0)//总集合，你要遍历的集合

	tempByIndexe:=GetByIndex('0',GraPh,'e')
	tempNumByteBye:=[10]byte{}
	for i:=0;i<len(tempByIndexe);i++{
		tempNumByteBye[i]=tempByIndexe[i]
	}//获得初始化集合

	StructQueue=append(StructQueue,tempNumByteBye)
	indexQUeue:=0
	for indexQUeue<len(StructQueue)&&visit[StructQueue[indexQUeue]]==false{
		visit[StructQueue[indexQUeue]]=true
		tempByIndexeIner:=StructQueue[indexQUeue]
		GS:=GraphStruct{}
		//获取开始集合到a的点有哪些
		tempa:=[10]byte{}
		flaga:=0
		for i:=0;i<len(tempByIndexeIner);i++{
			if tempByIndexeIner[i]==0{
				continue
			}
			if len(GraPh[tempByIndexeIner[i]]['a'])==1{
				tempa[flaga]=GraPh[tempByIndexeIner[i]]['a'][0]
				flaga++
			}
		}
		indexflag:=flaga
		//再求tempa集合的空闭包
		for i:=0;i<indexflag;i++{
			if int(tempa[i])!=0{
				tempbyE:=GetByIndex(tempa[i],GraPh,'e')
				tempbyE=tempbyE[1:]
				for j:=0;j<len(tempbyE);j++{
					tempa[flaga]=tempbyE[j]
					flaga++
				}

			}
		}
		GS.GraphStructByA=tempa

		tempb:=[10]byte{}
		flagb:=0
		for i:=0;i<len(tempByIndexeIner);i++{
			if len(GraPh[tempByIndexeIner[i]]['b'])==1{
				tempb[flagb]=GraPh[tempByIndexeIner[i]]['b'][0]
				flagb++
			}
		}
		indexflagb:=flagb
		for i:=0;i<indexflagb;i++{
			if int(tempb[i])!=0{
				tempbyE:=GetByIndex(tempb[i],GraPh,'e')
				tempbyE=tempbyE[1:]
				for j:=0;j<len(tempbyE);j++{
					tempb[flagb]=tempbyE[j]
					flagb++
				}
			}
		}
		GS.GraphStructByB=tempb
		Res[tempByIndexeIner]=GS
		if visit[tempa]==false{
			StructQueue=append(StructQueue,tempa)
		}
		if visit[tempb]==false{
			StructQueue=append(StructQueue,tempb)
		}
		indexQUeue++
	}

	fmt.Println("     集合","     ------a------  ","-------b------")
	for i:=0;i<len(StructQueue);i++{
		tempNums:=make([]int,0)
		for j:=0;j<len(StructQueue[i]);j++{
			if StructQueue[i][j]==0{
				break
			}
			tempNums=append(tempNums,int(StructQueue[i][j]))
		}
		sort.Ints(tempNums)
		fmt.Printf("{ ")
		for j:=0;j<len(StructQueue[i]);j++{
			if StructQueue[i][j]==0{
				break
			}
			fmt.Printf("%d,",tempNums[j]-'0')
		}
		fmt.Printf("}")
		fmt.Printf("")
		fmt.Printf("{")
		tempNums=make([]int,0)
		for j:=0;j<len(Res[StructQueue[i]].GraphStructByA);j++{
			if Res[StructQueue[i]].GraphStructByA[j]==0{
				break
			}
			tempNums=append(tempNums,int(Res[StructQueue[i]].GraphStructByA[j])-'0')
		}
		sort.Ints(tempNums)
		for j:=0;j<len(Res[StructQueue[i]].GraphStructByA);j++{
			if Res[StructQueue[i]].GraphStructByA[j]==0{
				break
			}
			fmt.Printf("%d,",tempNums[j])
		}
		fmt.Printf("}")
		fmt.Printf("")
		fmt.Printf("{")
		tempNums=make([]int,0)
		for j:=0;j<len(Res[StructQueue[i]].GraphStructByB);j++{
			if Res[StructQueue[i]].GraphStructByB[j]==0{
				break
			}
			tempNums=append(tempNums,int(Res[StructQueue[i]].GraphStructByB[j])-'0')
		}
		sort.Ints(tempNums)
		for j:=0;j<len(Res[StructQueue[i]].GraphStructByB);j++{
			if Res[StructQueue[i]].GraphStructByB[j]==0{
				break
			}
			fmt.Printf("%d,",tempNums[j])
		}
		fmt.Printf("}")
		fmt.Println()
	}
	mSum:=make(map[[10]byte]byte)
	var index byte=0
	for i:=0;i<len(StructQueue);i++{
		mSum[StructQueue[i]]='A'+index
		index++
	}
	fmt.Println("------------------------------------------------")

	fmt.Println("集合"," ----a------  ","   -------b------")
	for i:=0;i<len(StructQueue);i++{
		fmt.Printf("%c        ",mSum[StructQueue[i]])
		fmt.Printf("%c                   ",mSum[Res[StructQueue[i]].GraphStructByA])
		fmt.Printf("%c",mSum[Res[StructQueue[i]].GraphStructByB])
		fmt.Println()
	}

	for i:=0;i<len(StructQueue);i++{
		fmt.Printf("%c",mSum[StructQueue[i]])
		fmt.Printf("=")
		fmt.Printf("{")
		tempNum:=make([]int,0)
		for j:=0;j<len(StructQueue[i]);j++{
			if StructQueue[i][j]==0{
				break
			}
			tempNum=append(tempNum,int(StructQueue[i][j])-'0')
		}
		sort.Ints(tempNum)
		for j:=0;j<len(tempNum);j++ {
			fmt.Printf("%d ",tempNum[j])
		}
		fmt.Printf("}")
		fmt.Println()
	}

}


func GetByIndex(bs byte,Graph map[byte]map[byte][]byte,index byte) []byte {//入口函数，将开始节点的也放进去了
	ansByte:=make([]byte,0)
	ansByte=append(ansByte,bs)
	flagIndex:=0
	for len(Graph[ansByte[flagIndex]][index])!=0{
		for i:=0;i<len(Graph[ansByte[flagIndex]][index]);i++{
			ansByte=append(ansByte,Graph[ansByte[flagIndex]][index][i])
		}
		flagIndex++
	}
	return ansByte
}
